//
// Created by 卫志龙 on 2023/8/10.
//

#ifndef DATA_STUCT_STUDY_WZL_001_STACK_H
#define DATA_STUCT_STUDY_WZL_001_STACK_H

#include <iostream>

#ifndef ElementType
#define ElementType int
#endif

#define Status int
#define OK 1
#define ERROR -1

#define STACK_INIT_SIZE 5

typedef struct{
    ElementType *base;
    ElementType *top;
    int size;
}SqStack;

int GetCount(SqStack *&S) {
    return (int)((S->top - S->base)*4 / sizeof (ElementType));
}

Status InitStack(SqStack *&S) {
    S = (SqStack*) malloc(sizeof(SqStack));
    if (!S) return ERROR;
    S->base = (ElementType *)malloc(sizeof(ElementType)* STACK_INIT_SIZE);
    S->top = S->base;
    S->size = STACK_INIT_SIZE;
    return OK;
}
Status DestroyStack(SqStack *&S) {
    free(S->base);
    S = NULL;
    return OK;
}

Status ClearStack(SqStack *&S) {
    if (S == NULL) return ERROR;
    S->top = S->base;
    S->size = 0;
    return OK;
}

Status StackEmpty(SqStack *&S) {
    if (S == NULL) return ERROR;
    return *(S->top) == 0 ? 1 : 0;
}

ElementType GetTop(SqStack *&S) {
    if (!S || S->size == 0) return ERROR;
    return *(S->top - 1);
}

Status Push(SqStack *&S, ElementType e) {
    if (S == NULL) return ERROR;
    if (GetCount(S) == S->size) {
        S->base = (ElementType*) realloc(S->base , S->size*1.5);
    }
    *(S->top) = e;
    S->top++;
    return OK;
}

Status Pop(SqStack *&S, ElementType &e) {
    if (S == NULL) return ERROR;
    if (S->size == 0) return ERROR;
    e = *(S->top - 1);
    S->top--;
    return OK;
}

void PrintStack(SqStack *&S) {
    printf("stack: [");
    for (int i = 0 ; i < GetCount(S) ; i++) {
        printf("%d",S->base[i]);
        if (i != GetCount(S) - 1) printf(",");
    }
    printf("]\n");
}


#endif //DATA_STUCT_STUDY_WZL_001_STACK_H
